#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "tfrmstruct.h"
#include "tlr.h"
#include "tlrsyntaxhighlighter.h"
#include <QHBoxLayout>
#include <QSplitter>
#include <QStyleFactory>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QMimeData>
#include <QSerialPortInfo>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    //UI初始化
    {
        ui->setupUi(this);
        m_tabWidget->clear();
        ui->actionOpenFile->setText("打开文件");
        setAcceptDrops(true);
        ui->lbSerialPortStatus->setPixmap(m_pixmapSerialPortClose);

        ui->leParaStaAdd->setMinimumWidth(60);
        ui->leParaStaAdd->setMaximumWidth(60);
        ui->leDevPort->setMinimumWidth(60);
        ui->leDevPort->setMaximumWidth(60);
        ui->wgtOptEdit->setMinimumWidth(380);
        ui->wgtOptEdit->setMinimumWidth(100);
        ui->leSerialAddr->setMinimumWidth(60);
        ui->leSerialAddr->setMaximumWidth(60);
        ui->leDevIP->setText("192.168.0.11");
        ui->leDevPort->setText("2305");
        ui->leEquIdStr->setPlaceholderText("请输入设备识别字");
        ui->leParaStaAdd->setText("0");
        ui->leSerialAddr->setText("0");

        //设置文本框
        QFont nfont;
        nfont.setFamily("Courier");
        nfont.setFixedPitch(true);
        nfont.setPixelSize(11);
        m_teSource = new QTextEdit;
        m_teSource->setAcceptDrops(false);
        m_teSource->setFont(nfont);
        TLRSyntaxHighlighter *psyntaxhighlighter = new TLRSyntaxHighlighter(m_teSource->document());
        psyntaxhighlighter->setSyntaxFormat(TSyntaxFormat::syntaxFmtJson);
        //组装右边操作栏
        QWidget *pwgtcontent = new QWidget;
        QVBoxLayout *pvblcontent = new QVBoxLayout;
        pvblcontent->addWidget(m_tabWidget);
        pvblcontent->addWidget(ui->wgtOptPanel);
        pwgtcontent->setLayout(pvblcontent);
        ui->wgtOptPanel->setMinimumHeight(100);
        ui->wgtOptPanel->setMaximumHeight(100);
        pvblcontent->setContentsMargins(0,0,0,0);
        //组装界面
        QList<int> nsizes;
        nsizes.append(430);
        nsizes.append(300);
        QSplitter *pdragableboundary = new QSplitter(this);
        pdragableboundary->addWidget(m_teSource);
        pdragableboundary->addWidget(pwgtcontent);
        pdragableboundary->setCollapsible(0,false);
        pdragableboundary->setCollapsible(1,false);
        pdragableboundary->setSizes(nsizes);
        pdragableboundary->setStretchFactor(0,0);
        pdragableboundary->setStretchFactor(1,1);
        QHBoxLayout *phblcontent = new QHBoxLayout;
        phblcontent->addWidget(pdragableboundary);
        ui->centralwidget->setLayout(phblcontent);
        //居中显示
        int nwidth = 960;
        int nheight = 750;
        QDesktopWidget *pwgtdesktop = QApplication::desktop();
        if(pwgtdesktop) {
            setGeometry((pwgtdesktop->width()-nwidth) / 2, (pwgtdesktop->height()-nheight)/2,nwidth,nheight);
        }

        QStringList nserialbaudlist = {"1200","2400","4800","9600","19200","38400","57600","115200","921600"};
        ui->cbBaud->addItems(nserialbaudlist);
        dataToUI(TUIType::uiFrame);
        dataToUI(TUIType::uiSerialPort);

        slotToolTip("软件启动");
        setWindowTitle("结构体分析工具(版本v2022.03.16.1355)");

        qApp->setStyleSheet("file:///:/qss/haetstyle.css");
    }
    //信号槽
    {
        //文本变化
        connect(m_teSource,&QTextEdit::textChanged,this,&MainWindow::slotSourceTextChanged);
        //打开文件
        connect(ui->actionOpenFile,&QAction::triggered,this,&MainWindow::slotActionOpenFileTrigger);
        //翻页切换
        connect(m_tabWidget,&QTabWidget::currentChanged,this,&MainWindow::slotTabCurrentChanged);
        //读取按钮点击
        connect(ui->btnRd,&QPushButton::clicked,this,&MainWindow::slotBtnRdClicked);
        //下发按钮点击
        connect(ui->btnWr,&QPushButton::clicked,this,&MainWindow::slotBtnWrClicked);
        //控制按钮点击
        connect(ui->btnCtl,&QPushButton::clicked,this,&MainWindow::slotBtnCtlClicked);
        //打开关闭按钮点击
        connect(ui->btnOpenCloseSerialPort,&QPushButton::clicked,this,&MainWindow::slotBtnOpenCloseSerialPortClicked);
        //刷新串口按钮点击
        connect(ui->btnUpdateSerialPort,&QPushButton::clicked,this,&MainWindow::slotBtnUpdateSerialPortClicked);
        //提示消息
        connect(TLR::get(),&TLR::sigToolTip,this,&MainWindow::slotToolTip);

    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

/*
 * UI操作
 * nuitype : UI操作类型
 */
void MainWindow::dataToUI(const TUIType &nuitype)
{
    switch (nuitype) {
    //刷新界面
    case TUIType::uiFrame: {
        //清空tab
        QWidget *pwgttab = m_tabWidget->currentWidget();
        while(pwgttab) {
            m_tabWidget->removeTab(0);
            pwgttab->deleteLater();
            pwgttab = m_tabWidget->currentWidget();
        }
        //添加tab
        auto &nlrstructmodel = TLR::get()->m_lrStructModel;
        for(int i=0;i<nlrstructmodel.m_lrstructModel.size();i++) {
            TFrmStruct *pfrmstruct = new TFrmStruct;
            pfrmstruct->reset(i);
            m_tabWidget->addTab(pfrmstruct,nlrstructmodel.getStruct(i).name);
        }
        //模式
        if(nlrstructmodel.getMode() == "debug") {
            m_teSource->setVisible(true);
            ui->wgtOptPanel->setVisible(true);
        }
        else {
            m_teSource->setVisible(false);
            ui->wgtOptPanel->setVisible(false);
        }
        //设备识别字
        ui->leEquIdStr->setText(nlrstructmodel.getEquidStr());
        //通讯方式
        switch (nlrstructmodel.getCommType()) {
        case TCommType::ctNet: {
            ui->wgtNetPanel->setVisible(true);
            ui->wgtSerialPanel->setVisible(false);
            break;
        }
        case TCommType::ctSerial: {
            ui->wgtNetPanel->setVisible(false);
            ui->wgtSerialPanel->setVisible(true);
            break;
        }
        }
        break;
    }
        //串口信息
    case TUIType::uiSerialPort: {
        ui->cbSerialPort->clear();
        QString nportname = TLR::get()->getCurrentPortName();
        auto nserialportinfos = QSerialPortInfo::availablePorts();
        int nindex = 0;
        for(int i=0;i<nserialportinfos.size();i++) {
            QSerialPortInfo nserialportinfo = nserialportinfos.at(i);
            ui->cbSerialPort->addItem(nserialportinfo.description() + " (" + nserialportinfo.portName() + ")",nserialportinfo.portName());
            if(nserialportinfo.portName() == nportname) {
                nindex = i;
            }
        }
        ui->cbSerialPort->setCurrentIndex(nindex);
        break;
    }
    }
}

/*
 * 拖拽进入事件
 */
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    if(event->mimeData()->urls().size() == 1) {
        QString nfilepath = event->mimeData()->urls().front().toString();
        if(nfilepath.endsWith(".json")) {
            event->setAccepted(true);
        }
    }
}

/*
 * 拖拽放下事件
 */
void MainWindow::dropEvent(QDropEvent *event)
{
    if(event->mimeData()->urls().size() == 1) {
        QString nfilepath = event->mimeData()->urls().front().toLocalFile();
        QFile nfile(nfilepath);
        if(nfile.exists()) {
            nfile.open(QFile::ReadWrite);
            m_teSource->clear();
            m_teSource->setText(nfile.readAll());
            nfile.close();
        }
    }
}

/*
 * 文本变化
 */
void MainWindow::slotSourceTextChanged()
{
    TLR::get()->m_lrStructModel.loadFromJson(m_teSource->toPlainText().toUtf8());
    dataToUI(TUIType::uiFrame);
}

/*
 * 打开文件
 */
void MainWindow::slotActionOpenFileTrigger()
{
    QString nfilename = QFileDialog::getOpenFileName(this,"打开描述文件",QString(),"描述文件 (*.json)");
    QFile nfile(nfilename);
    if(nfile.exists()) {
        nfile.open(QFile::ReadWrite);
        m_teSource->clear();
        m_teSource->setText(nfile.readAll());
        nfile.close();
    }
}

/*
 * 翻页切换
 */
void MainWindow::slotTabCurrentChanged(int index)
{
    TLRStruct nlrstruct = TLR::get()->m_lrStructModel.getStruct(index);
    //设备起始地址
    ui->leParaStaAdd->setText(QString::number(nlrstruct.paraStaAdd));
}

/*
 * 读取按钮点击
 */
void MainWindow::slotBtnRdClicked()
{
    TFrmStruct *pfrmstruct = qobject_cast<TFrmStruct*>(m_tabWidget->currentWidget());
    if(pfrmstruct) {
        switch (TLR::get()->m_lrStructModel.getCommType()) {
        case TCommType::ctNet: {
            pfrmstruct->rdPara(ui->leEquIdStr->text(),ui->leParaStaAdd->text().toInt(),QHostAddress(ui->leDevIP->text()),ui->leDevPort->text().toInt());
            break;
        }
        case TCommType::ctSerial: {
            pfrmstruct->rdParaSerial(ui->leEquIdStr->text(),ui->leParaStaAdd->text().toInt(),ui->leSerialAddr->text().toInt());
            break;
        }
        }
    }
}

/*
 * 下发按钮点击
 */
void MainWindow::slotBtnWrClicked()
{
    TFrmStruct *pfrmstruct = qobject_cast<TFrmStruct*>(m_tabWidget->currentWidget());
    if(pfrmstruct) {
        pfrmstruct->wrPara(ui->leEquIdStr->text(),ui->leParaStaAdd->text().toInt(),QHostAddress(ui->leDevIP->text()),ui->leDevPort->text().toInt());
    }
}

/*
 * 控制按钮点击
 */
void MainWindow::slotBtnCtlClicked()
{
    TFrmStruct *pfrmstruct = qobject_cast<TFrmStruct*>(m_tabWidget->currentWidget());
    if(pfrmstruct) {
        pfrmstruct->ctlPara(ui->leEquIdStr->text(),ui->leParaStaAdd->text().toInt(),QHostAddress(ui->leDevIP->text()),ui->leDevPort->text().toInt());
    }
}

/*
 * 串口刷新点击
 */
void MainWindow::slotBtnUpdateSerialPortClicked()
{
    dataToUI(TUIType::uiSerialPort);
}

/*
 * 串口打开关闭按钮点击
 */
void MainWindow::slotBtnOpenCloseSerialPortClicked()
{
    //关闭
    if(ui->btnOpenCloseSerialPort->text() == "关闭") {
        TLR::get()->closeSerialPort();
        ui->btnOpenCloseSerialPort->setText("打开");
        ui->lbSerialPortStatus->setPixmap(m_pixmapSerialPortClose);
        ui->cbSerialPort->setEnabled(true);
        ui->cbBaud->setEnabled(true);
        ui->btnUpdateSerialPort->setEnabled(true);
    }
    //打开
    else if(ui->btnOpenCloseSerialPort->text() == "打开") {
        bool nret = TLR::get()->openSerialPort(ui->cbSerialPort->currentData().toString(),ui->cbBaud->currentText().toInt());
        if(nret) {
            ui->btnOpenCloseSerialPort->setText("关闭");
            ui->lbSerialPortStatus->setPixmap(m_pixmapSerialPortOpen);
            ui->cbSerialPort->setEnabled(false);
            ui->cbBaud->setEnabled(false);
            ui->btnUpdateSerialPort->setEnabled(false);
        }
    }
}

/*
 * 提示消息
 * ntooltip : 提示消息
 */
void MainWindow::slotToolTip(const QString &ntooltip)
{
    ui->lbToolTip->setText("[" + QTime::currentTime().toString() + "] " + ntooltip);
}

